# -*- coding: utf-8 -*-
"""
Created on Sat Nov 16 21:24:06 2019

@author: lsly
"""

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm

# 西瓜3.0α 样本数据
X=np.array([[0.697,0.46],[0.774,0.376],[0.634,0.264],[0.608,0.318],[0.556,0.215],
   [0.403,0.237],[0.481,0.149],[0.437,0.211],[0.666,0.091],[0.243,0.267],
   [0.245,0.057],[0.343,0.099],[0.639,0.161],[0.657,0.198],[0.36,0.37],
   [0.593,0.042],[0.719,0.103]])
Y=np.array([1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0])

# 支持向量机训练并将结果可视化
for c in [1E1,1E3,1E5]:
    for k in ['linear','rbf']:
        # 训练并提取支持向量
        clf=svm.SVC(C=c,kernel=k)  #C为惩罚系数,kernel是所用的核函数
        clf.fit(X,Y)               #fit函数对训练样本进行训练
        Xsp=X[clf.support_,:]      #参数support_为支持向量的索引号
        Ysp=Y[clf.support_]        #Xsp和Ysp分别为支持向量的特征和类标记
        # 画图
        plt.figure()
        plt.title('C=%.E, kernel=%s'%(c,k))
        # 画出正负样本(+和-符号表示)
        plt.scatter(X[Y==1,0],X[Y==1,1],marker='+',c='r',s=100)
        plt.scatter(X[Y==0,0],X[Y==0,1],marker='_',c='b',s=100)
        # 标出支持向量(画圈)(用marker='o'和c=''结合起来表示空心圆)
        plt.scatter(Xsp[Ysp==1,0],Xsp[Ysp==1,1],marker='o',c='',s=100,edgecolors='r')
        plt.scatter(Xsp[Ysp==0,0],Xsp[Ysp==0,1],marker='o',c='',s=100,edgecolors='b')
        # 画决策线
        x1,x2=np.meshgrid(np.linspace(min(X[:,0]),max(X[:,0]),100),
                  np.linspace(min(X[:,1]),max(X[:,1]),100))
        z=clf.decision_function(np.c_[x1.reshape(-1),x2.reshape(-1)]).reshape(100,100)
        # ↑   decision_function返回决策函数值，也即wx+b的值，
        #     另外还有函数predict可以返回类标记，比如1,0
        plt.contour(x1,x2,z,colors='k',linestyles=['--','-','--'],levels=[-1,0,1])